<!--
 * @Author: 瞿旺兴 18774621495@163.com
 * @Date: 2022-05-23 19:54:01
 * @LastEditors: 瞿旺兴 18774621495@163.com
 * @LastEditTime: 2022-06-24 11:09:37
 * @FilePath: \nien-vue3-admin\src\views\index\components\ReceivableSum.vue
 * @Description: 总应收
-->
<template>
  <div ref="receivableRef" :class="{'isFull': isFull}">
    <el-card>
      <template #header>
        <div class="card-header">
          <span class="title">总应收</span>
          <div class="btn-box">
            <el-button :icon="isFull ? ZoomOut : ZoomIn" @click="handleFullScreen"></el-button>
          </div>
        </div>
      </template>
      <el-tabs v-model="activeName">
        <el-tab-pane
          v-for="(item, index) in tabData" 
          :key="index"
          :name="item"
          :label="item"
        ></el-tab-pane>
      </el-tabs>
      <div>
        <div class="receive-chart-wrapper">
          <div id="tongbi" class="chart"></div>
        </div>            
        <div class="receive-chart-wrapper">
          <div id="huanbi" class="chart"></div>
        </div>  
      </div>      
    </el-card>
  </div>
</template>

<script setup lang="ts">
import {
  ZoomIn,
  ZoomOut,
} from '@element-plus/icons-vue'
import { ref, reactive, onMounted, onBeforeUnmount, computed, watch } from 'vue'
import * as echarts from 'echarts'
import screenfull from 'screenfull'
import useWsStore from '@/store/modules/websocket'

const wsStore = useWsStore()

const activeName = ref<string>()

const tabData = ref([])
const lineDataMap = reactive<Map<string, any>>(new Map()) 
const barDataMap = reactive<Map<string, any>>(new Map()) 
// 当前xAxis data
const xAxisData = computed(() => lineDataMap.get(activeName.value)?.xAxisData || [])

const getData = () => {
  // 线形图
  wsStore.send(wsStore.SIGN_MAP.LINE_CHART_PUSH)
  // 柱状图
  wsStore.send(wsStore.SIGN_MAP.COLUMNAR_CHART_PUSH)
}
getData()
// 接受ws初始化数据
wsStore.onMessage({ sign: wsStore.SIGN_MAP.LINE_CHART_PUSH }, ({ data }) => {
  console.log(data, '线形图')
  tabData.value = data.map((item: { deptName: string; last: any[]; now: any[] }) => {
    lineDataMap.set(item.deptName, {
      last: item.last.map((i: { totalReceivables: any }) => i.totalReceivables),
      now: item.now.map((i: { totalReceivables: any }) => i.totalReceivables),
      xAxisData: item.now.map((i: { dateTime: any }) => i.dateTime),
    })
    return item.deptName
  })
  if (!activeName.value) {
    // 初始化
    activeName.value = tabData.value[0]
  }
  initLineChart()
})
wsStore.onMessage({ sign: wsStore.SIGN_MAP.COLUMNAR_CHART_PUSH }, ({ data }) => {
  console.log(data, '柱状图')
  data.forEach((item: { deptName: string; last: any; now: any }) => {
    barDataMap.set(item.deptName, {
      last: item.last,
      now: item.now,
    })
  })
  
  initBarChart()
})

watch([activeName], () => {
  initLineChart()
  initBarChart()
})

let myChart1: echarts.ECharts, myChart2: echarts.ECharts

const getLineOption = () => ({
  title: {
    text: '同比上月',
  },
  tooltip: {
    trigger: 'axis',
    formatter: (params: any[]) => {
      let res = `<div class='chart-tooltip'>
          <div class='title'><span> ${ params[0].axisValueLabel }</span>${ activeName.value }</div>
      `
      params.forEach((item: { color: any; seriesName: any; value: any }) => {
        res += `
              <p class='tool-item'><i class='dot' style='background-color: ${ item.color }'><i  style='border-color:${ item.color }'></i></i><span>${ item.seriesName }：</span>${ item.value }</p>
          `
      })
      res += '</div>'
      return res
    },
  },
  legend: {
    right: 40,
    data: ['上月', '本月'],
  },
  grid: {
    top: 48,
    left: 16,
    right: 16,
    bottom: 16,
    containLabel: true,
  },
  xAxis: [
    {
      type: 'category',
      boundaryGap: false,
      data: xAxisData.value,
      axisLine: {
        show: false,
      },
      axisTick: {
        show: false,
      },
    },
  ],
  yAxis: [
    {
      type: 'value',
    },
  ],
  series: [
    {
      name: '上月',
      type: 'line',
      lineStyle: {
        color: '#0084FF',
      },
      itemStyle: {
        color: '#0084FF',
      },
      showSymbol: false,
      areaStyle: {
        opacity: 0.4,
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: '#0084FF',
          },
          {
            offset: 1,
            color: '#fff',
          },
        ]),
      },
      emphasis: {
        focus: 'series',
      },
      data: lineDataMap.get(activeName.value)?.last || [],
    },
    {
      name: '本月',
      type: 'line',
      lineStyle: {
        color: '#13DFFF',
      },
      itemStyle: {
        color: '#13DFFF',
      },
      showSymbol: false,
      areaStyle: {
        opacity: 0.4,
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          {
            offset: 0,
            color: '#13DFFF',
          },
          {
            offset: 1,
            color: '#fff',
          },
        ]),
      },
      emphasis: {
        focus: 'series',
      },
      data: lineDataMap.get(activeName.value)?.now || [],
    },
  ],
})

const getBarOption = () => {
  const op = {
    title: {
      text: '环比上月',
    },
    tooltip: {
      trigger: 'axis',
      formatter: (params: any[]) => {
        let res = `<div class='chart-tooltip'>
          <div class='title'><span> ${ params[0].axisValueLabel }</span>${ activeName.value }</div>
      `
        params.forEach((item: { color: any; seriesName: any; value: any }) => {
          res += `
              <p class='tool-item'><i class='rect' style='background-color: ${ item.color }'></i><span>${ item.seriesName }：</span>${ item.value }</p>
          `
        })
        res += '</div>'
        return res
      },
    },
    grid: {
      top: 48,
      left: 16,
      right: 16,
      bottom: 16,
      containLabel: true,
    },
    legend: {
      right: 40,
      data: ['上月', '本月'],
    },
    xAxis: [
      {
        type: 'category',
        data: barDataMap.get(activeName.value)?.now.map(i => i.dateTime),
        axisPointer: {
          type: 'shadow',
        },
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
      },
    ],
    yAxis: [
      {
        type: 'value',
        name: '',
      },
    ],
    series: [
      {
        name: '上月',
        type: 'bar',
        barWidth: 6,
        itemStyle: {
          color: '#0084FF',
          borderRadius: [2, 2, 0, 0],
        },
        data: barDataMap.get(activeName.value)?.last.map(i => i.totalReceivables),
      },
      {
        name: '本月',
        type: 'bar',
        barWidth: 6,
        itemStyle: {
          color: '#13DFFF',
          borderRadius: [2, 2, 0, 0],
        },
        tooltip: {
        },
        data: barDataMap.get(activeName.value)?.now.map(i => i.totalReceivables),
      },
    ],
  }
  console.log(op, 22222)

  return op
}
const initLineChart = () => {
  if (!myChart1) {
    myChart1 = echarts.init(document.getElementById('tongbi'))
  }
  myChart1.setOption(getLineOption(), true)
}
const initBarChart = () => {
  if (!myChart2) {
    myChart2 = echarts.init(document.getElementById('huanbi'))
  }
  myChart2.setOption(getBarOption(), true)
}

onMounted(() => {
  initLineChart()
  initBarChart()
})
const resize = (e: { currentTarget: { innerWidth: number } }) => {
  if (e.currentTarget.innerWidth < 860) {
    return
  }
  myChart1.resize()
  myChart2.resize()
}

document.addEventListener('resize', resize)
onBeforeUnmount(() => {
  document.removeEventListener('resize', resize)
})

const receivableRef = ref(null)
const isFull = ref(false)
const handleFullScreen = () => {
  if (screenfull.isEnabled) {
    isFull.value = !isFull.value 
    screenfull.toggle(receivableRef.value)
  }
}

</script>

<style lang="less" scoped>
.isFull {
  padding: 16px;
  background-color: #fff;
}
.receive-chart-wrapper {
  height: 350px;
  margin-top: 32px;
  & + .receive-chart-wrapper {
    margin-top: 16px;
  }
  h3 {
    height: 48px;
    line-height: 48px;
    font-family: PingFangSC-Medium;
    font-size: 14px;
    color: #010d19;
    float: left;
    padding-left: 16px;
  }
  .chart {
    height: 100%;
  }
}
.card-header {
  display: flex;
  justify-content: space-between;
  .title {
    font-family: PingFangSC-Medium;
    font-size: 16px;
    color: #010d19;
    line-height: 22px;
  }
  .btn-box {
    .el-button {
      padding: 4px;
      height: auto;
      &:hover,
      &:focus,
      &:visited,
      &:active {
        background: #e9eef7;
        color: #000;
      }
    }
  }
}
::v-deep .chart-tooltip {
  width: 144px;
  height: 74px;
  padding: 0 2px;
  border-radius: 8px;
  .title {
    font-family: PingFangSC-Regular;
    font-size: 14px;
    color: #010d19;
    line-height: 20px;
    margin-bottom: 8px;
    span {
      margin-right: 8px;
    }
  }
  .tool-item {
    display: flex;
    margin-bottom: 0;
    color: #010d19;
    align-items: center;
    & + p {
      margin-top: 6px;
    }
    span {
      color: #7a8298;
    }
  }
  .rect {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 2px;
    margin-right: 8px;
  }
  .dot {
    display: inline-block;
    width: 18px;
    height: 2px;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-right: 8px;
    i {
      display: inline-block;
      width: 8px;
      height: 8px;
      border-radius: 6px;
      border-width: 2px;
      border-style: solid;
      background-color: #fff;
    }
  }
}
</style>